/*
 * @Author: huangtianyang 916072572@qq.com
 * @Date: 2022-12-02 17:04:13
 * @LastEditors: huangtianyang
 * @LastEditTime: 2023-07-25 11:39:42
 * @FilePath: \cxl-admin\src\axios\index.ts
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
import axios, { AxiosInstance } from 'axios'
import { ElMessage } from 'element-plus'
import { storage } from '@/store/sessionStorage'
import router from '@/router'

/**
 * 定义不需要携带token访问的接口
 */
const notToekn: string[] = ['/api/system/admin/login']

/**
 * 从启动的环境拉取访问的地址
 */
const url = import.meta.env.VITE_HOST

//请求携带的token变量值
let token = ''

//是否需要刷新token
let isRefreshToken = false

/**
 * 初始化axios
 */
const instance: AxiosInstance = axios.create({
    baseURL: url,
    timeout: 10000
})

/**
 * 设置 Content-Type
 */
instance.defaults.headers.post['Content-Type'] = 'application/json'
instance.defaults.headers.get['Content-Type'] = 'application/x-www-form-urlencoded'

/**
 * 添加请求拦截器
 */
instance.interceptors.request.use(
    function (config: any) {
        /**
         * 请求前判断 token 是否为空
         * 若为空，则从本地storage拉去token
         */
        if (token === '') {
            token = storage.get('token')
        }
        isRefreshToken = false
        /**
         * 在发送请求之前，判断接口是不是需要携带token
         */
        if (notToekn.includes(config.url)) {
            config.headers.Authorization = ''
            token = ''
        } else {
            config.headers.ContentType = 'application/x-www-form-urlencoded'

            //监听请求路径是否是刷新token
            if (config.url == '/api/system/admin/refreshToken') {
                isRefreshToken = true
                config.headers.Authorization = 'Bearer ' + storage.get('refreshToken')
            } else {
                config.headers.Authorization = 'Bearer ' + token
            }
        }

        return config
    },
    function (error) {
        // 对请求错误做些什么
        return Promise.reject(error)
    }
)

/**
 * 添加响应拦截器
 */
instance.interceptors.response.use(
    function (response) {
        // 2xx 范围内的状态码都会触发该函数。
        // console.log('url:', response.config.url)
        // console.log( `${response.config.method === 'get' ? 'get:' : 'data:'}`, response.config.method === 'get' ? response.config.params : response.config.data)
        console.log('%cresult:', 'color:#000;font-size:16px;background:#ebebeb;padding:0 4px', response.data)
        let result: any = {
            data: undefined
        }

        // 对响应数据做点什么
        if (response.data.value === 200) {
            result = response
            //是刷新token请求，则清楚本地token
            if (isRefreshToken) {
                storage.remove('token')
                isRefreshToken = false
                token = ''
            }
            return result
        } else if (response.data.value === 30012) {
            //token 无效

            //清除本地数据
            sessionStorage.clear()
            //跳转的登录页面
            router.replace('/login')
            console.log('token 无效')
            return {
                data: {
                    value: 0
                }
            }
        } else {
            return response
        }
    },
    function (error) {
        // 超出 2xx 范围的状态码都会触发该函数。
        console.log('error', error, error.response?.data.value)
        if ([30012, 30011].includes(error.response?.data.value)) {
            console.log('重新登录！')
            router.replace('/login')
            sessionStorage.clear()
            ElMessage.error('登录信息已失效！')
        } else if (Number(error.response?.data.value) === 30002) {
            console.log('没有权限！')
            ElMessage.error('没有权限！')
        }
        //对错误提示进行弹窗提示
        let { message } = error
        if (message === 'Network Error') {
            message = '后端接口连接异常'
        } else if (message.includes('timeout')) {
            message = '系统接口请求超时'
        } else if (message.includes('Request failed with status code')) {
            message = '系统接口' + message.substr(message.length - 3) + '异常'
        }
        // ElMessage.error(message)

        // 对响应错误做点什么
        return Promise.reject(error)
    }
)

export default instance
